home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS04.ADF
/
C
/
speechtoy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1985-11-16
|
41KB
|
1,100 lines
/* speechtoy.c */
/* This program was written to show the use of gadgets in a window.
* Thus one menu, one auto requester, but lots of gadget types.
* Also for the sake of example, two mutual exclude gadgets
* (female/male) are shown that perform a function that might
* be better implemented as a toggle image, in a manner similar
* to that shown in the inflection Mode gadget.
* Yet again for the sake of example, the proportional gadgets
* are generated dynamicly (that is, copied from a template and
* filled in), whereas most gadgets are declared staticly in the
* struct declaration, which saves the initialization code space.
* Lastly, for the sake of example, this program is extremely
* verbose in the way of comments. Hope you don't mind.
*/
/* Written by David Lucas */
#include "exec/types.h"
#include "exec/exec.h"
#include "intuition/intuition.h"
#include "intuition/intuitionbase.h"
#include "graphics/regions.h"
#include "graphics/copper.h"
#include "graphics/gels.h"
#include "graphics/gfxbase.h"
#include "devices/keymap.h"
#include "hardware/blit.h"
#include "devices/narrator.h"
#include "libraries/translator.h"
#define DEBUG
/* Revision number is used on calls to OpenLibrary
* to let the system know what revision level the
* program was written for. Usually refers to the
* ROM release number or the release number of a
* disk based library.
*/
#define REVISION 1
#define CONTWINDW 320 /* Overall Control Window Width / Height */
#define CONTWINDH 112
#define FACEWINDW 80 /* Overall Face Window Width / Height */
#define FACEWINDH 50
#define YMOUTHCENTER 27 /* Pixels from top edge */
#define XMOUTHCENTER 35 /* Pixels from left edge */
/* Pen numbers to draw gadget borders/images/text with */
#define REDP 3 /* color in register 3 once was red */
#define BLKP 2 /* color in register 2 once was black */
#define WHTP 1 /* color in register 1 once was white */
#define BLUP 0 /* color in register 0 once was blue */
#define STRINGSIZE 512 /* the length of the English and phonetic buffers */
#define NUMPROPS 4 /* number of proportional gadgets */
#define RNGFREQ (MAXFREQ - MINFREQ) +1 /* Ranges of proportional data */
#define RNGRATE (MAXRATE - MINRATE) +1
#define RNGPITCH (MAXPITCH - MINPITCH) +1
#define RNGVOL (MAXVOL - MINVOL) +1
struct TextAttr TestFont = /* Needed for opening screen */
{
(STRPTR)"topaz.font",
TOPAZ_EIGHTY, 0, 0
};
/* speech specific stuff */
BYTE audio_chan[] = {3, 5, 10, 12}; /* Which audio channels to use */
struct Library *TranslatorBase; /* Pointer to translator library vectors */
struct MsgPort talk_port; /* Message port for the say's I/O */
struct MsgPort read_port; /* Message port for the say's I/O */
struct narrator_rb voice_io; /* IO Request block, narrator flavor */
struct mouth_rb mouth_io; /* IO Request block, narrator flavor */
UBYTE NarratorOpenError = 0; /* indicative of the Open return */
UBYTE TranslatorError = 0; /* indicative of a Translations success */
UBYTE NarratorError = 0; /* indicative of a Narrations success */
/* these are used for drawing and erasing the mouth in the face window */
int lastwidth, usedwidth, lastheight, usedheight = 0;
/* String Gadgets ******************************************************
* First the string gadgets.
* 1) because the Phonetic string is refreshed programaticly (that is,
* deleted and added again) quite often, and doing this requires the
* use of RefreshGadgets(), and this causes gadgets that are closer to
* the beginning of the list than the gadget given to RefreshGadgets()
* to flicker.
* 2) because they don't flicker when OTHER gadgets (ie female/male,
* coming up) are deleted and added.
*/
/* These'll be used to put a nice double line border around
* each of the two string gadgets.
*/
/* y,x pairs drawn as a connected line. Be sure to have an even
* number of arguments (ie complete pairs).
*/
USHORT StrVectors[] = {
0, 0, 295, 0, 295, 13, 0, 13,
0, 1, 294, 1, 294, 12, 1, 12,
1, 1
};
struct Border StrBorder = {
-4, -3, /* initial offsets, gadget relative */
WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
9, /* number of vectors */
StrVectors, /* pointer to the actual array of vectors */
NULL /* no next Border, can point to another border */
};
/* The same undo buffer is used for both string gadgets,
* if they were different sizes, this would be sized to largest
*/
UBYTE UndoBuffer[STRINGSIZE];
/* English String Gadget is where the user can type in English */
UBYTE EnglBuffer[STRINGSIZE] = "This is amiga speaking."; /* default text */
struct StringInfo EnglInfo = {
EnglBuffer, /* pointer to I/O buffer */
UndoBuffer, /* pointer to undo buffer */
0, /* buffer position */
STRINGSIZE, /* maximum number of chars, including trailing NULL */
0, 0, /* first char in display, undo positions */
24, /* number of chars (currently) in the buffer */
0, 0, 0, /* position variables calculated by Intuition */
NULL, /* no pointer to RastPort */
0, /* not a LongInt string gadget */
NULL /* no pointer to alternate keymap */
};
struct IntuiText EnglText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM1, /* DrawMode */
0, -13, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
"English:", /* pointer to Text */
NULL /* no pointer to NextText */
};
struct Gadget EnglStrGadget = {
NULL, /* pointer to Next Gadget */
11, 59, 288, 10, /* (Left Top Width Height) Hit Box */
GADGHCOMP, /* Flags */
RELVERIFY, /* Activation flags */
STRGADGET, /* Type */
(APTR)&StrBorder, /* pointer to Border Image */
NULL, /* no pointer to SelectRender */
&EnglText, /* pointer to GadgetText */
0, /* no MutualExclude */
(APTR)&EnglInfo, /* pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* Phonetic string gadget is where the program puts the translated string,
* necessating a call to RefreshGadgets(),
* and is where the user can type in Phonemes.
*/
UBYTE PhonBuffer[STRINGSIZE] = "DHIHS IHZ AHMIY3GAH SPIY4KIHNX.";
struct StringInfo PhonInfo = {
PhonBuffer, /* pointer to input buffer */
UndoBuffer, /* pointer to undo buffer */
0, /* initial buffer position */
STRINGSIZE, /* maximum number of chars, including trailing NULL */
0, 0, /* display, undo positions */
32, /* number of chars (currently) in the buffer */
0, 0, 0, /* position variables calculated by Intuition */
NULL, /* no pointer to RastPort */
NULL, /* not a LongInt string gadget */
NULL /* no pointer to alternate keymap */
};
struct IntuiText PhonText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM1, /* DrawMode */
0, -13, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
"Phonetics:", /* pointer to Text */
NULL /* no pointer to NextText */
};
struct Gadget PhonStrGadget = {
&EnglStrGadget, /* pointer to Next Gadget */
11, 85, 289, 10, /* (Left Top Width Height) Hit Box */
GADGHCOMP, /* Flags */
RELVERIFY, /* Activation flags */
STRGADGET, /* Type */
(APTR)&StrBorder, /* pointer to Border Image */
NULL, /* no pointer to SelectRender */
&PhonText, /* pointer to GadgetText */
0, /* no MutualExclude */
(APTR)&PhonInfo, /* pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* Now come the Boolean Gadgets.
* The female/male pair shows the simplest implementation I could think
* of to show how you can do mutual-exclude type things yourself.
* They are two toggle gadgets that use highlight image. The program
* starts with one selected, and then if either of them are hit,
* both toggle. Until either of them is hit again.
* Gadgets must be deleted and added whenever you want to
* change structure member values that intuition expects to be coming
* from the user, not a program (like the SELECTED bit in flags).
* Note that certain structure values CAN be changed programaticly
* without all this broohaha. Haha. Consult the intuition manual.
*/
/* Female Toggle (Highlight Image) (Quasi mutual exclude with Male Toggle) */
struct Image FemaleImage = {
0, 0, /* LeftEdge, TopEdge (relative to gadget) */
20, 10, 1, /* Width, Height, Depth */
NULL, /* pointer to ImageData */
0x1, 0x0 /* PlanePick, PlaneOnOff */
};
struct Gadget FemaleGadget = {
&PhonStrGadget, /* pointer to Next Gadget */
134, 34, 20, 10, /* (Left Top Width Height) Hit Box */
GADGIMAGE | GADGHCOMP, /* Flags */
RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, /* Activation flags */
BOOLGADGET, /* Type */
(APTR)&FemaleImage, /* pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
NULL, /* no pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* Male Toggle (Highlight Image) (Quasi mutual Exclude with above) *********/
struct Image MaleImage = {
0, 0, /* LeftEdge, TopEdge (relative to gadget) */
20, 10, 1, /* Width, Height, Depth */
NULL, /* pointer to ImageData */
0x1, 0x0 /* PlanePick, PlaneOnOff */
};
struct Gadget MaleGadget = {
&FemaleGadget, /* pointer to Next Gadget */
154, 34, 20, 10, /* (Left Top Width Height) Hit Box */
GADGIMAGE | GADGHCOMP | SELECTED, /* Flags */
RELVERIFY | GADGIMMEDIATE | TOGGLESELECT | ACTIVATE, /* Activation flags
*/
BOOLGADGET, /* Type */
(APTR)&MaleImage, /* pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
NULL, /* no pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* This boolean toggle gadget has an alternate image that indicates
* selection. The image stays flipped until it gets another hit. (it toggles)
*/
/* Inflection Mode Toggle (AltImage)
******************************************/
struct Image HumanImage = {
0, 0, /* LeftEdge, TopEdge (relative to gadget) */
40, 20, 1, /* Width, Height, Depth */
NULL, /* pointer to ImageData */
0x1, 0x0 /* PlanePick, PlaneOnOff */
};
struct Image RobotImage = {
0, 0, /* LeftEdge, TopEdge (relative to gadget) */
40, 20, 1, /* Width, Height, Depth */
NULL, /* pointer to ImageData */
0x1, 0x0 /* PlanePick, PlaneOnOff */
};
struct Gadget ModeGadget = {
&MaleGadget, /* pointer to Next Gadget */
134, 2, 40, 20, /* (Left Top Width Height) Hit Box */
GADGIMAGE | GADGHIMAGE, /* Flags */
RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, /* Activation flags */
BOOLGADGET, /* Type */
(APTR)&HumanImage, /* pointer to GadgetRender */
(APTR)&RobotImage, /* pointer to SelectRender */
NULL, /* no pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* This gadget is diasabled, as the feature is not implemented here. */
/* Face Toggle (image) *****************************************************/
struct Image FaceImage = {
0, 0, /* LeftEdge, TopEdge (relative to gadget) */
40, 10, 1, /* Width, Height, Depth */
NULL, /* pointer to ImageData */
0x1, 0x0 /* PlanePick, PlaneOnOff */
};
struct Gadget FaceGadget = {
&ModeGadget, /* pointer to Next Gadget */
134, 23, 40, 10, /* (Left Top Width Height) Hit Box */
GADGIMAGE | GADGHCOMP, /* Flags */
RELVERIFY | GADGIMMEDIATE | TOGGLESELECT, /* Activation flags */
BOOLGADGET, /* Type */
(APTR)&FaceImage, /* no pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
NULL, /* pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* This is a hit (as opposed to toggle) gadget that starts the translation.*/
/* Translate Hit (Highlight image) *****************************************/
USHORT TransVectors[] = {
1, 0, 74, 0, 74, 9, 1, 9, 1, 0
};
struct Border TransBorder = {
0, 0, /* initial offsets, gadget relative */
WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
5, /* number of vectors */
TransVectors, /* pointer to the actual array of vectors */
NULL /* no next Border, can point to another border */
};
struct IntuiText TranslateIText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM2, /* DrawMode */
2, 1, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
"Translate",/* pointer to Text */
NULL /* no pointer to NextText */
};
struct Gadget TranslateGadget = {
&FaceGadget, /* pointer to Next Gadget */
228, 45, 76, 10, /* (Left Top Width Height) Hit Box */
GADGHCOMP, /* Flags */
RELVERIFY | GADGIMMEDIATE, /* Activation flags */
BOOLGADGET, /* Type */
(APTR)&TransBorder, /* no pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
&TranslateIText, /* pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* This is a hit (as opposed to toggle) gadget that starts the narration. */
/* Speak Hit (Highlight Image) *********************************************/
USHORT SpeakVectors[] = {
1, 0, 42, 0, 42, 9, 1, 9, 1, 0
};
struct Border SpeakBorder = {
0, 0, /* initial offsets, gadget relative */
WHTP, BLUP, JAM1, /* pens (fore, back) and drawmode */
5, /* number of vectors */
SpeakVectors, /* pointer to the actual array of vectors */
NULL /* no next Border, can point to another border */
};
struct IntuiText SpeakIText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM2, /* DrawMode */
2, 1, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
"Speak", /* pointer to Text */
NULL /* no pointer to NextText */
};
struct Gadget SpeakGadget = {
&TranslateGadget, /* pointer to Next Gadget */
260, 71, 44, 10, /* (Left Top Width Height) Hit Box */
GADGHCOMP, /* Flags */
RELVERIFY | GADGIMMEDIATE, /* Activation flags */
BOOLGADGET, /* Type */
(APTR)&SpeakBorder, /* pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
&SpeakIText, /* pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* Now the proportional gadgets. */
/* Proportional Gadgets **************************************************/
/* The following variables are used to create proportional Gadgets.
* These variables will be filled in with copies of the generic
* Gadgetry below.
*/
SHORT PropCount = 0; /* index to next available Gadget */
struct IntuiText PTexts[NUMPROPS]; /* these get copies of TPropText */
struct Image PImages[NUMPROPS]; /* dummy AUTOKNOB Images are required
*/
struct PropInfo PInfos[NUMPROPS]; /* these get copies of TPropInfo */
struct Gadget Props[NUMPROPS]; /* these get copies of TPropGadget */
struct IntuiText TPropText = {
WHTP, BLUP, /* FrontPen, BackPen */
JAM1, /* DrawMode */
0, -10, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
NULL, /* pointer to Text will be filled at runtime */
NULL /* no pointer to NextText */
};
struct PropInfo TPropInfo = {
AUTOKNOB | FREEHORIZ, /* Flags */
0, 0, /* Pots: Horiz, Vert: both start at 0 */
0x1FFF, 0x1FFF, /* Bodies: Horiz is 1/8, Vert is 1/8 */
0, 0, 0, 0, 0, 0 /* System usage stuff */
};
/* this is the template for the Gadget of a horizontal Proportional Gadget */
struct Gadget TPropGadget = {
&SpeakGadget, /* pointer to NextGadget */
7, 12, 115, 10, /* Select Box Left Top Width Height */
GADGHCOMP | GADGIMAGE, /* Flags */
GADGIMMEDIATE | RELVERIFY, /* Activation flags */
PROPGADGET, /* Type */
NULL, /* pointer to Image filled in later since this is AUTOKNOB */
NULL, /* no pointer to SelectRender */
NULL, /* no pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* SpecialInfo proportional data filled in later */
0, /* no ID */
NULL /* no pointer to special data */
};
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
/* Only one menu. Most of you (I assume) are as egocentric as I am.
* If so, this menu and the requster involved are a must do.
*/
ULONG MenuNumber;
ULONG TheMenu;
ULONG TheItem;
struct IntuiText MenuItemText = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
0, /* Left Edge */
0, /* Top */
&TestFont, /* pointer to TextFont */
"About SpeechToy...", /* text */
NULL /* next */
};
struct MenuItem MyMenuItem = {
NULL, /* pointer to next item */
0, /* left */
0, /* top */
150, /* width */
8, /* height */
ITEMTEXT | ITEMENABLED | HIGHCOMP, /* flags */
0, /* no mutual exclude */
(APTR)&MenuItemText, /* Render */
NULL, /* pointer to alternate image */
NULL, /* Command "amiga" char */
NULL, /* Sub Item */
MENUNULL /* nextselect */
};
struct Menu MyMenu = {
NULL, /* pointer to next menu */
0,0,120,0, /* left,0,Width,0 */
MENUENABLED, /* flags */
"SpeechToy Menu", /* menu name */
&MyMenuItem /* First Item in list */
};
struct IntuiText ReqText1 = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
5, /* Left Edge */
23, /* Top */
&TestFont, /* pointer to TextFont */
"AnyTown, USA 91827", /* text */
NULL /* next */
};
struct IntuiText ReqText2 = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
5, /* Left Edge */
13, /* Top */
&TestFont, /* pointer to TextFont */
"12345 Main Street, ", /* text */
&ReqText1 /* next */
};
struct IntuiText ReqText3 = {
BLUP, /* Front Pen */
WHTP, /* Back pen */
JAM2, /* Draw Mode */
5, /* Left Edge */
3, /* Top */
&TestFont, /* pointer to TextFont */
"David M. Lucas, ", /* text */
&ReqText2 /* next */
};
struct IntuiText OKIText = {
BLUP, WHTP, /* FrontPen, BackPen */
JAM2, /* DrawMode */
6, 3, /* LeftEdge, TopEdge (relative to gadget) */
&TestFont, /* pointer to TextFont */
"OK", /* pointer to Text */
NULL /* no pointer to NextText */
};
struct Requester *AboutRequester;
USHORT autoret;
struct Window *ControlWindow;
struct Window *FaceWindow;
struct IntuiMessage *MyIntuiMessage;
struct NewWindow NewControlWindow = {
00, 11, /* start LeftEdge, TopEdge */
CONTWINDW, CONTWINDH, /* start Width, Height */
-1, -1, /* DetailPen, BlockPen */
GADGETUP | CLOSEWINDOW | MENUPICK, /* IDCMP FLAGS (can be NULL) */
WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE
| GIMMEZEROZERO | ACTIVATE,/* Flags (can be NULL) */
&Props[NUMPROPS-1], /* Pointer to FirstGadget */
NULL, /* no pointer to first CheckMark */
"SpeechToy", /* Title (can be NULL) */
NULL, /* no Pointer to Screen */
NULL, /* no Pointer to BitMap */
20, 20, /* Minimum Sizable to (w/h) */
CONTWINDW, CONTWINDH, /* Maximum Sizable to (w/h) */
WBENCHSCREEN /* Type of screen window appears in */
};
struct NewWindow NewFaceWindow = {
CONTWINDW, 11, /* start LeftEdge, TopEdge */
FACEWINDW, FACEWINDH, /* start Width, Height */
-1, -1, /* DetailPen, BlockPen */
NULL, /* IDCMP FLAGS */
WINDOWDRAG | WINDOWDEPTH | GIMMEZEROZERO | ACTIVATE,/* Flags (can be NULL)
*/
NULL, /* no Pointer to FirstGadget */
NULL, /* no Pointer to first CheckMark */
NULL, /* no Title */
NULL, /* no Pointer to Screen */
NULL, /* no Pointer to BitMap */
20, 20, /* Minimum Sizable to (w/h) (not sizeable) */
FACEWINDW, FACEWINDH, /* Maximum Sizable to (w/h) (not sizeable) */
WBENCHSCREEN /* Type of screen window appears in */
};
USHORT FemaleIData[] = {
/* ---- - These nibbles matter to image. */
0x0000, 0x0000,
0x00F0, 0x0000,
0x0198, 0x0000,
0x030C, 0x0000,
0x0198, 0x0000,
0x00F0, 0x0000,
0x0060, 0x0000,
0x01F8, 0x0000,
0x0060, 0x0000,
0x0000, 0x0000
};
USHORT MaleIData[] = {
/* ---- - These nibbles matter to image. */
0x0000, 0x0000,
0x003E, 0x0000,
0x000E, 0x0000,
0x0036, 0x0000,
0x01E0, 0x0000,
0x0330, 0x0000,
0x0618, 0x0000,
0x0330, 0x0000,
0x01E0, 0x0000,
0x0000, 0x0000
};
USHORT HumanIData[] = {
/* ---- ---- -- These nibbles matter to image. */
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0007,0x9E00,0x0000,
0x0001,0x8600,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x2000,0x0000,
0x0000,0x1000,0x0000,
0x0000,0x0800,0x0000,
0x0000,0x7C00,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x7800,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000
};
USHORT RobotIData[] = {
/* ---- ---- -- These nibbles matter to image. */
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0007,0x9E00,0x0000,
0x0004,0x9200,0x0000,
0x0007,0x9E00,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0001,0xF800,0x0000,
0x0001,0x0800,0x0000,
0x0001,0xF800,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000
};
USHORT FaceIData[] = {
/* ---- ---- -- These nibbles matter to image. */
0x0000, 0x0000, 0x0000,
0x0000, 0x1800, 0x0000,
0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000,
0x2000, 0x0000, 0x0400,
0x2000, 0x0000, 0x0400,
0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000,
0x0000, 0x1800, 0x0000,
0x0000, 0x0000, 0x0000
};
USHORT *FemaleIData_chip;
USHORT *MaleIData_chip;
USHORT *HumanIData_chip;
USHORT *RobotIData_chip;
USHORT *FaceIData_chip;
/** start of code ***************************/
main()
{
/* Open those libraries that the program uses directly */
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", REVISION)) == 0) {
#ifdef DEBUG
printf("Can't open the intuition library\n");
#endif
MyCleanup();
Exit(FALSE);
}
if ((GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", REVISION)) == 0) {
#ifdef DEBUG
printf("Can't open the graphics library\n");
#endif
MyCleanup();
Exit(FALSE);
}
if ((TranslatorBase = (struct Library *)
OpenLibrary("translator.library", REVISION)) == 0) {
#ifdef DEBUG
printf("Can't open the translator library\n");
#endif
MyCleanup();
Exit(FALSE);
}
/* Open the device */
if ((NarratorOpenError = OpenDevice("narrator.device", 0, &voice_io, 0)) != 0) {
#ifdef DEBUG
printf("Can't open the narrator device\n");
#endif
MyCleanup();
Exit(FALSE);
}
/* This is where the proportional gadgets are set up, using
* the templates that were declared staticly.
*/
for(PropCount = 0; PropCount < NUMPROPS; PropCount++) {
PTexts[PropCount] = TPropText;
Props[PropCount] = TPropGadget;
PInfos[PropCount] = TPropInfo;
Props[PropCount].GadgetText = (struct IntuiText *)&PTexts[PropCount];
Props[PropCount].GadgetRender = (APTR)&PImages[PropCount];
Props[PropCount].SpecialInfo = (APTR)&PInfos[PropCount];
switch (PropCount) {
case 0:
PTexts[PropCount].IText = "Sample Freq:";
if (DEFFREQ == MAXFREQ)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((DEFFREQ - MINFREQ) << 16) / (MAXFREQ
- MINFREQ);
break;
case 1:
PTexts[PropCount].IText = "Rate:";
Props[PropCount].TopEdge += 22;
Props[PropCount].NextGadget = &Props[PropCount-1];
if (DEFRATE == MAXRATE)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((DEFRATE - MINRATE) << 16) / (MAXRATE
- MINRATE);
break;
case 2:
PTexts[PropCount].IText = "Pitch:";
Props[PropCount].LeftEdge += 181;
Props[PropCount].NextGadget = &Props[PropCount-1];
if (DEFPITCH == MAXPITCH)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((DEFPITCH - MINPITCH) << 16) /
(MAXPITCH - MINPITCH);
break;
case 3:
PTexts[PropCount].IText = "Volume:";
Props[PropCount].TopEdge += 22;
Props[PropCount].LeftEdge += 181;
Props[PropCount].NextGadget = &Props[PropCount-1];
if (DEFVOL == MAXVOL)
PInfos[PropCount].HorizPot = 65535;
else
PInfos[PropCount].HorizPot = ((DEFVOL - MINVOL) << 16) / (MAXVOL -
MINVOL);
break;
/* the following for lattice bug */
case 4: break;
}
}
/* Now allocate memory accessable by the chips for images */
if (InitImages() != TRUE) {
#ifdef DEBUG
printf("Couldn't Allocate Images in chip memory.\n");
#endif
MyCleanup();
Exit(FALSE);
}
/* Set up the write port, allocate the signal, and the message */
talk_port.mp_Node.ln_Type = NT_MSGPORT;
talk_port.mp_Flags = 0;
if ((talk_port.mp_SigBit = AllocSignal(-1)) == -1) {
#ifdef DEBUG
printf("Couldn't Allocate talk Signal bit\n");
#endif
MyCleanup();
Exit(FALSE);
}
talk_port.mp_SigTask = (struct Task *) FindTask((char *) NULL);
NewList(&talk_port.mp_MsgList);
/* Set up the read port, allocate the signal, and the message */
read_port.mp_Node.ln_Type = NT_MSGPORT;
read_port.mp_Flags = 0;
if ((read_port.mp_SigBit = AllocSignal(-1)) == -1) {
#ifdef DEBUG
printf("Couldn't Allocate read Signal bit\n");
#endif
MyCleanup();
Exit(FALSE);
}
read_port.mp_SigTask = (struct Task *) FindTask((char *) NULL);
NewList(&read_port.mp_MsgList);
/* Set up the write channel information */
voice_io.ch_masks = (audio_chan);
voice_io.nm_masks = sizeof(audio_chan);
voice_io.mouths = 0;
voice_io.message.io_Message.mn_ReplyPort = &talk_port;
voice_io.message.io_Command = CMD_WRITE;
voice_io.message.io_Offset = 0;
voice_io.message.io_Data = (APTR)PhonBuffer;
voice_io.message.io_Length = strlen(PhonBuffer);
voice_io.message.io_Message.mn_Length = sizeof(voice_io);
/* Set up the read channel information */
mouth_io.voice = voice_io;
mouth_io.width = 0;
mouth_io.height = 0;
mouth_io.voice.message.io_Message.mn_ReplyPort = &read_port;
mouth_io.voice.message.io_Command = CMD_READ;
mouth_io.voice.message.io_Error = 0;
if ((ControlWindow = (struct Window *)OpenWindow(&NewControlWindow)) ==
NULL) {
#ifdef DEBUG
printf("Couldn't open the control window.\n");
#endif
MyCleanup();
Exit(FALSE);
}
/* fill background of window */
SetAPen(ControlWindow->RPort, BLKP);
RectFill(ControlWindow->RPort,0,0,CONTWINDW,CONTWINDH);
RefreshGadgets(&Props[NUMPROPS-1],ControlWindow,NULL);
SetMenuStrip(ControlWindow, &MyMenu);
for (;;) { /* ever wait for a signal and process it */
/* wait lets the rest of the system run, this program sleeps */
Wait(1 << ControlWindow->UserPort->mp_SigBit);
/* now check to see to what we owe the intrusion */
while (MyIntuiMessage=(struct IntuiMessage *)
GetMsg(ControlWindow->UserPort))
switch (MyIntuiMessage->Class) {
case MENUPICK:
ReplyMsg(MyIntuiMessage);
menumessage(MyIntuiMessage, ControlWindow);
break;
case GADGETUP: /* reply, then process */
ReplyMsg(MyIntuiMessage);
gadgetmessage(MyIntuiMessage, ControlWindow);
break;
case CLOSEWINDOW: /* bye */
ReplyMsg(MyIntuiMessage);
while (MyIntuiMessage = (struct IntuiMessage *)
GetMsg(ControlWindow->UserPort))
ReplyMsg(MyIntuiMessage);
MyCleanup();
Exit(TRUE);
break;
default:
ReplyMsg(MyIntuiMessage);
#ifdef DEBUG
printf("Unhandled Message Received.\n");
#endif
break;
} /* switch */
} /* for */
} /* main */
/* a MENUPICK has been received, this routine takes the appropriate action */
menumessage(message, w)
struct IntuiMessage *message;
struct Window *w;
{
USHORT code;
code = (message->Code);
switch (MENUNUM(code)) {
case 0:
switch (ITEMNUM(code)) {
case 0:
AutoRequest(ControlWindow, &ReqText3, NULL, &OKIText, 0, 0, 280,
47);
break;
}
break;
}
}
/* a GADGETUP has been received, this routine takes the appropriate action */
gadgetmessage(message, w)
struct IntuiMessage *message;
struct Window *w;
{
USHORT i;
long PropRange;
if (message->IAddress == (APTR)&ModeGadget) {
if (ModeGadget.Flags & SELECTED)
voice_io.mode = ROBOTICF0;
else
voice_io.mode = NATURALF0;
}
else if (message->IAddress == (APTR)&FaceGadget) {
if (FaceGadget.Flags & SELECTED) {
voice_io.mouths = 1; /* tell the write that reads will be
forthcomming */
if ((FaceWindow = (struct Window *)OpenWindow(&NewFaceWindow)) ==
NULL) {
#ifdef DEBUG
printf("Couldn't open the mouth window.\n");
#endif
MyCleanup();
Exit(FALSE);
}
SetAPen(FaceWindow->RPort, WHTP); /* Set pen to White */
RectFill(FaceWindow->RPort, 0, 0, FACEWINDW, FACEWINDH);
SetAPen(FaceWindow->RPort, BLUP); /* Set pen to Blue */
RectFill(FaceWindow->RPort, 10, 10, 20, 15);
RectFill(FaceWindow->RPort, 50, 10, 60, 15);
SetAPen(FaceWindow->RPort, REDP); /* Set pen to Red */
RectFill(FaceWindow->RPort, XMOUTHCENTER-15, YMOUTHCENTER,
XMOUTHCENTER+15, YMOUTHCENTER);
}
else {
voice_io.mouths = 0;
CloseWindow(FaceWindow);
FaceWindow = NULL;
}
}
/* Since this program changes a flag that intuition expects only
* the user to change (SELECTED bit), this program has to remove,
* then change, then add this gadget. Then by passing the address
* of this gadget to RefreshGadgets(), only the gadgets from here
* to the start of the list will be refreshed, which minimizes
* the visible flash that RefreshGadgets() can introduce.
* If one of the two gadgets (female/male) is hit, toggle the
* selection of the other gadget (since the gadget hit was toggled
* by intuition when it was hit).
*/
else if (message->IAddress == (APTR)&FemaleGadget) {
if (FemaleGadget.Flags & SELECTED)
voice_io.sex = FEMALE;
else
voice_io.sex = MALE;
i = RemoveGadget(ControlWindow, &MaleGadget);
MaleGadget.Flags ^= SELECTED;
AddGadget(ControlWindow, &MaleGadget, i);
RefreshGadgets(&MaleGadget, ControlWindow, NULL);
}
else if (message->IAddress == (APTR)&MaleGadget) {
if (MaleGadget.Flags & SELECTED)
voice_io.sex = MALE;
else
voice_io.sex = FEMALE;
i = RemoveGadget(ControlWindow, &FemaleGadget);
FemaleGadget.Flags ^= SELECTED;
AddGadget(ControlWindow, &FemaleGadget, i);
RefreshGadgets(&MaleGadget, ControlWindow, NULL);
}
/* Since the program changes the contents of the string gadgets'
* buffer and it's size, which is something else intuition doesn't
* expect a program (as opposed to the user) to do. The program
* must remove, then change, then add this gadget, and then by
* passing the address of this gadget to RefreshGadgets(), only the
* gadgets from here to the start of the list will be refreshed,
* which minimizes the visible flash that RefreshGadgets() can introduce.
*/
else if (message->IAddress == (APTR)&TranslateGadget) {
i = RemoveGadget(ControlWindow, &PhonStrGadget);
if ((TranslatorError = Translate((APTR)EnglBuffer, EnglInfo.NumChars,
(APTR)PhonBuffer, PhonInfo.MaxChars)) != 0) {
#ifdef DEBUG
printf("Translator won't. (%lx)\n",TranslatorError);
#endif
DisplayBeep(ControlWindow->WScreen); /* flash this screen */
}
voice_io.message.io_Length = strlen(PhonBuffer);
/* Hey! NumChars includes the terminating NULL. This must be done. */
PhonInfo.NumChars = voice_io.message.io_Length + 1;
AddGadget(ControlWindow, &PhonStrGadget, i);
RefreshGadgets(&PhonStrGadget, ControlWindow, NULL);
}
else if (message->IAddress == (APTR)&SpeakGadget) {
if ((NarratorError = SendIO(&voice_io)) != 0) {
#ifdef DEBUG
printf("Narrator won't. (%lx)\n",NarratorError);
#endif
DisplayBeep(ControlWindow->WScreen); /* flash this screen */
}
else {
if (voice_io.mouths == 1) {
while(mouth_io.voice.message.io_Error != ND_NoWrite) {
DoIO(&mouth_io);
SetAPen(FaceWindow->RPort, WHTP);
RectFill(FaceWindow->RPort,XMOUTHCENTER-usedwidth,
YMOUTHCENTER-usedheight,XMOUTHCENTER+usedwidth,
(YMOUTHCENTER-usedheight)+lastheight);
lastwidth = mouth_io.width;
usedwidth = (lastwidth >> 1) + lastwidth;
lastheight = mouth_io.height;
usedheight = lastheight >> 1;
SetAPen(FaceWindow->RPort, REDP);
Move(FaceWindow->RPort, XMOUTHCENTER - usedwidth, YMOUTHCENTER);
Draw(FaceWindow->RPort, XMOUTHCENTER, YMOUTHCENTER - usedheight);
Draw(FaceWindow->RPort, XMOUTHCENTER + usedwidth, YMOUTHCENTER);
Draw(FaceWindow->RPort, XMOUTHCENTER, YMOUTHCENTER + (mouth_io.height - usedheight));
Draw(FaceWindow->RPort, XMOUTHCENTER - usedwidth, YMOUTHCENTER);
}
mouth_io.voice.message.io_Error = 0;
}
}
}
else if (message->IAddress == (APTR)&EnglStrGadget); /* do nothing */
else if (message->IAddress == (APTR)&PhonStrGadget); /* do nothing */
else if (message->IAddress == (APTR)&Props[0]) {
PropRange = RNGFREQ;
voice_io.sampfreq = (( (PInfos[0].HorizPot >> 1) * PropRange) >> 15) + MINFREQ;
#ifdef DEBUG
printf("Freq. = %ld\n", voice_io.sampfreq);
#endif
}
else if (message->IAddress == (APTR)&Props[1]) {
PropRange = RNGRATE;
voice_io.rate = (((PInfos[1].HorizPot >> 1) * PropRange) >> 15) + MINRATE;
#ifdef DEBUG
printf("Rate = %ld\n", voice_io.rate);
#endif
}
else if (message->IAddress == (APTR)&Props[2]) {
PropRange = RNGPITCH;
voice_io.pitch = (((PInfos[2].HorizPot >> 1) * PropRange) >> 15) + MINPITCH;
#ifdef DEBUG
printf("Pitch = %ld\n", voice_io.pitch);
#endif
}
else if (message->IAddress == (APTR)&Props[3]) {
PropRange = RNGVOL;
voice_io.volume = (((PInfos[3].HorizPot >> 1) * PropRange) >> 15) + MINVOL;
#ifdef DEBUG
printf("Vol. = %ld\n", voice_io.volume);
#endif
}
#ifdef DEBUG
else printf("Unhandled gadget up received!\n");
#endif
}
/* Deallocate any memory, and close all windows/screens/devices/libraries
* in reverse order to make programming easier. And be sure to check
* that the open/allocation was successful before closing/deallocating.
*/
MyCleanup()
{
if (read_port.mp_SigBit != -1)
FreeSignal(talk_port.mp_SigBit);
if (talk_port.mp_SigBit != -1)
FreeSignal(talk_port.mp_SigBit);
if (FaceWindow != 0)
CloseWindow(FaceWindow);
if (ControlWindow != 0)
CloseWindow(ControlWindow);
/* freeimages makes sure image allocation was successful */
freeimages();
if (NarratorOpenError == 0)
CloseDevice(&voice_io);
if (TranslatorBase != 0)
CloseLibrary(TranslatorBase);
if (GfxBase != 0)
CloseLibrary(GfxBase);
if (IntuitionBase != 0)
CloseLibrary(IntuitionBase);
return(0);
}
/* Allocate chip memory for gadget images, and set the pointers in the
* corresponding image structures to point to these images.
* This must be done because the program could be loaded into expansion
* memory (off the side of the box), which the custom chips cannot access.
*/
InitImages()
{
extern USHORT *FemaleIData_chip;
extern USHORT *MaleIData_chip;
extern USHORT *HumanIData_chip;
extern USHORT *RobotIData_chip;
extern USHORT *FaceIData_chip;
int i;
if ((FemaleIData_chip = (USHORT *)AllocMem(sizeof(FemaleIData),MEMF_CHIP)) == 0)
return(FALSE);
if ((MaleIData_chip = (USHORT *)AllocMem(sizeof(MaleIData),MEMF_CHIP)) == 0)
return(FALSE);
if ((HumanIData_chip = (USHORT *)AllocMem(sizeof(HumanIData),MEMF_CHIP)) == 0)
return(FALSE);
if ((RobotIData_chip = (USHORT *)AllocMem(sizeof(RobotIData),MEMF_CHIP)) == 0)
return(FALSE);
if ((FaceIData_chip = (USHORT *)AllocMem(sizeof(FaceIData),MEMF_CHIP)) == 0)
return(FALSE);
for (i=0; i<20; i++)
FemaleIData_chip[i] = FemaleIData[i];
for (i=0; i<20; i++)
MaleIData_chip[i] = MaleIData[i];
for (i=0; i<60; i++)
HumanIData_chip[i] = HumanIData[i];
for (i=0; i<60; i++)
RobotIData_chip[i] = RobotIData[i];
for (i=0; i<30; i++)
FaceIData_chip[i] = FaceIData[i];
FemaleImage.ImageData = FemaleIData_chip;
MaleImage.ImageData = MaleIData_chip;
HumanImage.ImageData = HumanIData_chip;
RobotImage.ImageData = RobotIData_chip;
FaceImage.ImageData = FaceIData_chip;
return(TRUE);
}
freeimages()
{
extern USHORT *FemaleIData_chip;
extern USHORT *MaleIData_chip;
extern USHORT *HumanIData_chip;
extern USHORT *RobotIData_chip;
extern USHORT *FaceIData_chip;
if (FaceIData_chip != 0)
FreeMem(FaceIData_chip, (sizeof(FaceIData),MEMF_CHIP));
if (RobotIData_chip != 0)
FreeMem(RobotIData_chip, (sizeof(RobotIData),MEMF_CHIP));
if (HumanIData_chip != 0)
FreeMem(HumanIData_chip, (sizeof(HumanIData),MEMF_CHIP));
if (MaleIData_chip != 0)
FreeMem(MaleIData_chip, (sizeof(MaleIData),MEMF_CHIP));
if (FemaleIData_chip != 0)
FreeMem(FemaleIData_chip, (sizeof(FemaleIData),MEMF_CHIP));
}